package genericdemo;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: jinshengyuan
 * Date: 2019-03-14
 * Time: 21:10
 * description: 泛型的使用
 * 为什么要使用泛型？
 * 1.没有泛型的情况下，任何Object类型及其子类的对象都可以添加集合中，这样存在类型安全问题；
 * 2.在强制类型转换时可能抛ClassCaseException异常
 *
 **/
public class GenericDemo {


    /**
     * 未使用泛型之前按
     */
    @Test
    public void problem(){
        List list = new ArrayList();
        list.add(44);
        list.add(23);
        list.add(33);
        list.add("aaa");//任何对象可添加


        for (int i = 0; i < list.size() ; i++) {
            int num = (Integer) list.get(i); //强制转换为int时，抛出ClassCaseException异常,java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap')
            System.out.println(num);
        }
    }

    /**
     * 使用泛型,指定了什么类型，集合添加就是什么类型，不存在类型安全问题
     */
    @Test
    public void useGeneric(){
        List<Integer> list = new ArrayList();
        list.add(44);
        list.add(23);
        list.add(33);

        for (int i = 0; i < list.size(); i++) {
            int aa = list.get(i);
            System.out.println(aa);
        }

        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //list.forEach( obj -> System.out.println(obj));
    }

    /**
     *  泛型于继承的关系
     *  1. 通配符
     */
    @Test
    public void testOne(){
        //问题的引入
        List<Object> listA = null;
        List<String> listB = null;
        //listA = listB; 这样是不行的


        //上述问题使用通配符 ?  可解决，说明 List<?> 是 List<Object> 与  List<String> 的父类
        List<?> list = null;
        List<Object> list1 = null;
        List<String> list2 = null;

        list = list1;
        list = list2;

        //3. List<? extends T> ： 小于等于的意思，即：T 类型及其子类

        List<? extends Number> numbers = null;
        List<Integer> integerList = null;
        List<Object> objectList = null;
        numbers = integerList;//这样是可以的，因为Integer是Number的子类

        //numbers = objectList;//这样是不行的，因为Object是Number的 父类


        //4. List<? super T> ：  大于等于的意思，即：T 类型及其父类
        List<? super Number> integers = null;
        List<Object> objectListA = null;
        List<Integer> integerListA = null;
        integers = objectListA;//这样是可以的，因为Object是Number的 父类

        //integers = integerListA;//这样是不可以的，因为Integer是Number的子类
    }
}
